package com.zuipin.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.zuipin.entity.SysMenu;
import com.zuipin.entity.SysRole;
import com.zuipin.entity.SysRoleMenu;
import com.zuipin.entity.SysRoleResource;
import com.zuipin.entity.SysUser;
import com.zuipin.framework.emuns.ErrorCode;
import com.zuipin.framework.result.Result;
import com.zuipin.mapper.SysMenuMapper;
import com.zuipin.mapper.SysResourceMapper;
import com.zuipin.mapper.SysRoleMenuMapper;
import com.zuipin.mapper.SysRoleResourceMapper;
import com.zuipin.service.ISysMenuService;
import com.zuipin.util.DateUtils;
import com.zuipin.util.Pagination;
import com.zuipin.vo.MenuTreeNode;
import com.zuipin.vo.ModityPermissionVo;
import com.zuipin.vo.PermissionVo;

/**
 * 菜单服务实现
 * 
 * @ClassName: SysMenuSer5viceImpl
 * @Description: TODO
 * @author  robot
 * @date 2017年09月147日 09:21:08
 */
@Service
public class SysMenuServiceImpl implements ISysMenuService {
	
	@Resource
	private SysMenuMapper			sysMenuMapper;
	
	@Resource
	private SysResourceMapper		sysResourceMapper;
	
	@Resource
	private SysRoleMenuMapper		sysRoleMenuMapper;
	
	@Resource
	private SysRoleResourceMapper	sysRoleResourceMapper;
	
	@Override
	public SysMenu findById(Long id) {
		return sysMenuMapper.findById(id);
	}
	
	@Override
	public void insert(SysMenu sysMenu) {
		sysMenuMapper.insert(sysMenu);
	}
	
	@Override
	public void update(SysMenu sysMenu) {
		sysMenuMapper.update(sysMenu);
	}
	
	@Override
	public void delete(Long id) {
		sysMenuMapper.delete(id);
		
	}
	
	@Override
	public List<SysMenu> seachSysMenu(SysMenu sysMenu, Pagination page) {
		return sysMenuMapper.seachSysMenu(sysMenu, page);
	}
	
	@Override
	public List<SysMenu> findByRoleId(Long roleId, Integer status) {
		// TODO Auto-generated method stub
		return sysMenuMapper.findByRoleId(roleId, status);
	}
	
	/**
	 * @remark 查询菜单树(只查询有权限的菜单)
	 * @param node
	 * @param userId
	 * @param sysId
	 * @param searchMode=0 只查询出有权限的模块（菜单） searchMode=1 查询所有模块（菜单），有权限hasPermission=1，无权限hasPermission=0 
	 * @return
	 */
	// @Override
	// public List<MenuTreeNode> getMenuTree(Long userId, Long roleId, Long sysId, Integer searchMode) {
	// List<MenuTreeNode> treeNodes = new ArrayList<>();
	// // 构建虚拟头部节点
	// MenuTreeNode headNode = new MenuTreeNode(0l, "模块树");
	// // 获取第一级菜单
	// List<MenuTreeNode> childMenus = sysMenuMapper.queryMenus(null, SysMenu.level1, roleId, userId, sysId, searchMode);
	// for (MenuTreeNode menuTreeNode : childMenus) {
	// menuTreeNode.setChildMenus(menuTreeRecursively(menuTreeNode, roleId, userId, sysId, searchMode));
	// }
	// headNode.setChildMenus(childMenus);
	// treeNodes.add(headNode);
	// return treeNodes;
	// }
	
	@Override
	public List<MenuTreeNode> getMenuTree(Long userId, Long roleId, String sysId, Integer searchMode, Integer isCommon) {
		// 权限数据
		Map<Long, Long> permissionMap = new HashMap<>();
		if (userId != null && userId.equals(SysUser.SA)) {
			permissionMap = null;// SA默认拥有所有权限
		} else {
			List<SysRoleMenu> roleMenus = sysRoleMenuMapper.queryMenuByPermission(userId, roleId, SysRole.ENABLE);
			permissionMap.putAll(roleMenus.stream().collect(Collectors.toMap(SysRoleMenu::getMenuId, SysRoleMenu::getMenuId)));
		}
		
		List<MenuTreeNode> treeNodes = new ArrayList<>();
		// 构建虚拟头部节点
		MenuTreeNode headNode = new MenuTreeNode(MenuTreeNode.DEFAULT_HEAD_NODE, "模块树");
		// 获取第一级菜单
		List<MenuTreeNode> childMenus = initMenuTree(0l, sysId, permissionMap, searchMode, isCommon);
		headNode.setChildMenus(childMenus);
		treeNodes.add(headNode);
		return treeNodes;
	}
	
	/**
	 * 加载树型菜单,与权限无关
	 * @param menuId
	 * @param sysId
	 * @param permissionMap 
	 * @param searchMode 
	 * @return
	 */
	private List<MenuTreeNode> initMenuTree(Long menuId, String sysId, Map<Long, Long> permissionMap, Integer searchMode, Integer isCommon) {
		List<SysMenu> childMenus = sysMenuMapper.queryMenuByParent(menuId, sysId, isCommon);
		if (childMenus != null && childMenus.size() > 0) {
			List<MenuTreeNode> childNodes = new ArrayList<>();
			for (SysMenu sysMenu : childMenus) {
				MenuTreeNode menuTreeNode = new MenuTreeNode(sysMenu);
				// 有权限
				if (permissionMap == null || permissionMap.get(sysMenu.getId()) != null) {
					menuTreeNode.setHasPermission(MenuTreeNode.HAS_PERMISSION);
					childNodes.add(menuTreeNode);
				} else {
					menuTreeNode.setHasPermission(MenuTreeNode.NO_PERMISSION);
					if (searchMode.equals(SysMenu.SEARCH_MODE_DIFF_SHOW)) {
						childNodes.add(menuTreeNode);
					}
				}
				
				if (menuTreeNode.getMenuLevel() < 3) {
					List<MenuTreeNode> grandchilds = initMenuTree(menuTreeNode.getId(), sysId, permissionMap, searchMode, isCommon);
					menuTreeNode.setChildMenus(grandchilds);
				}
			}
			return childNodes;
		}
		return null;
	}
	
	/**
	 * @remark 递归查询菜单
	 * @author chenjunjie
	 * @param node
	 * @param userId
	 * @param sysId
	 * @return
	 */
	private List<MenuTreeNode> menuTreeRecursively(MenuTreeNode node, Long roleId, Long userId, Long sysId, Integer searchMode) {
		List<MenuTreeNode> childMenus = sysMenuMapper.queryMenus(node.getId(), null, roleId, userId, sysId, searchMode);
		if (childMenus != null && childMenus.size() > 0) {
			// List<MenuTreeNode> childNodes = convertMenuToTreeNode(childMenus);
			for (MenuTreeNode menuTreeNode : childMenus) {
				if (menuTreeNode.getMenuLevel() < 3) {
					menuTreeNode.setChildMenus(menuTreeRecursively(menuTreeNode, roleId, userId, sysId, searchMode));
				}
			}
			return childMenus;
		}
		return null;
	}
	
	/**
	 * @author chenjunjie
	 * @category 将List<SysMenu> 转化成 List<MenuTreeNode>
	 * @param menus
	 * @return
	 */
	private List<MenuTreeNode> convertMenuToTreeNode(List<SysMenu> menus) {
		List<MenuTreeNode> nodes = new ArrayList<>();
		if (menus != null && menus.size() > 0) {
			menus.stream().forEach(m -> {
				nodes.add(new MenuTreeNode(m));
			});
		}
		return nodes;
	}
	
	@Override
	public Result setPermission(ModityPermissionVo permissionVo) {
		Result result = new Result<>();
		// 删除旧权限
		Long roleId = permissionVo.getRoleId();
		sysMenuMapper.deleteMenuPermissionByRole(roleId);
		sysResourceMapper.deleteResourcePermissionByRole(roleId);
		List<PermissionVo> permissions = permissionVo.getPermissions();
		if (permissions != null && permissions.size() > 0) {
			permissions.stream().filter(t -> (t.getM() != null && t.getM() > 0)).forEach(t -> {
				sysRoleMenuMapper.insert(new SysRoleMenu(roleId, t.getM()));
			});
			permissions.stream().filter(t -> (t.getR() != null && t.getR() > 0)).forEach(t -> {
				sysRoleResourceMapper.insert(new SysRoleResource(roleId, t.getR()));
			});
		}
		result.setErrorCode(ErrorCode.SUCCESS);
		result.setCnMessage("权限设置成功");
		result.setMessage("权限设置成功");
		return result;
	}
	
	@Override
	public Result<SysMenu> addOrUpdateSysMenu(SysMenu sysMenu) {
		Result<SysMenu> result = new Result<>();
		String now = DateUtils.getCurrentDateTime();
		SysMenu parent = null;
		String menuPath = "";
		if (sysMenu.getParentId() != null) {
			parent = findById(sysMenu.getParentId());
			if (parent != null) {
				sysMenu.setParentId(parent.getId());
				sysMenu.setMenuLevel(parent.getMenuLevel() + 1);
				menuPath = parent.getPath();
			}
		}
		
		if (sysMenu.getParentId() == null || parent == null) {
			sysMenu.setParentId(SysMenu.DEFAULT_ROOT_MENU);
			sysMenu.setMenuLevel(SysMenu.level1);
			menuPath = SysMenu.DEFAULT_ROOT_MENU.toString();
		}
		
		try {
			sysMenu.setIsPublic(SysMenu.NOT_PUBLIC);
			sysMenu.setUpdateTime(now);
			if (sysMenu.getId() == null) {
				sysMenu.setCreateId(sysMenu.getUpdateId());
				sysMenu.setCreateTime(now);
				
				sysMenu.setDelFlag(SysMenu.DEL_NO);
				sysMenu.setMenuStatus(SysMenu.ENABLE);
				insert(sysMenu);
				result.setErrorCode(ErrorCode.SUCCESS);
				result.setMessage("新增模块(菜单)成功!");
				result.setCnMessage("新增模块(菜单)成功!");
				result.setData(sysMenu);
			} else {
				result.setErrorCode(ErrorCode.SUCCESS);
				result.setMessage("更新模块(菜单)成功!");
				result.setCnMessage("更新模块(菜单)成功!");
				result.setData(null);
			}
			sysMenu.setPath(menuPath + "/" + sysMenu.getId());
			update(sysMenu);
		} catch (Exception e) {
			// 违反唯一约束
			if (e.getMessage().indexOf(SysMenu.UQ_MENU_CODE_INDEX) >= 0) {
				result.setErrorCode(ErrorCode.OBJECT_EXIST);
				result.setMessage("此编号已经存在,请重新输入");
				result.setCnMessage("此编号已经存在,请重新输入");
				result.setData(null);
				return result;
			} else {
				result.setErrorCode(ErrorCode.DB_EXCEPTION);
				result.setData(null);
				return result;
			}
		}
		
		return result;
	}
	
}
